/**
 * @Author Xin Xiao
 * @Description
 * @Version 1.0.0
 * @Date 2021/3/01 17:23 下午
 * @Copyright MIN-Group；国家重大科技基础设施——未来网络北大实验室；深圳市信息论与未来网络重点实验室
 */

	var Block = require("../encoding/Block")
	var Encoder = require("../encoding/Encoder")
	var ComponentType = require("../encoding/TLV").ComponentType
	var TLV = require("../encoding/TLV")
	const encoding = require('../encoding')

/**
 * 表示一个 TTL Tlv
 * @Description 
 * 1. 格式如下：
 * TTL = TTL-TYPE TLV-LENGTH NonNegativeInteger
 */

class TTL extends encoding.SelfEncodingBase {
	
	constructor(){
		super()
		this.ttl = 0n    //bigint
	}

	/**
	 * @description 根据 TLV Block 初始化一个 TTL
	 * @param {Block} block
	 */
	buildTTLByBlock(block){
		return this.wireDecode(block)
	}

	/**
	 * @description 将 TTL 线速编码为一个 TLV
	 * @param {Encoder} encoder
	 * @return {number}
	 * @throws
	 */
	wireEncode(encoder){
		let totalLength = 0
		try {
			//编码 TLV-VALUE
			let tmpLen = encoder.prependNonNegativeInteger(this.ttl)
			totalLength += tmpLen

			//编码 TLV-LENGTH
			tmpLen = encoder.prependVarNumber(BigInt(totalLength))
			totalLength += tmpLen

			//编码 TLV-TYPE
			tmpLen = encoder.prependVarNumber(ComponentType.TlvTTL)
			totalLength += tmpLen

			return totalLength
		} catch (error) {
			throw error
		}
	}

	/**
	 * @description 从 TLV Block 中解码出一个TTL
	 * @param {Block} block
	 */
	wireDecode(block){
		let value
		try {
			//检查Type是否正确
			TLV.expectType(block.getType(),ComponentType.TlvTTL)

			value = TLV.readNonNegativeInteger(block.getValue(), 0 ,block.getLength())
			this.ttl = BigInt(value)
		} catch (error) {
			throw error
		}
	}

	/**
   * Set ttl
   * @params {bigint} ttl
   */
	setTTL(ttl){
		this.ttl = ttl
	}
	/**
	 * Get ttl
	 * @return {bigint} ttl
	 */
	getTtl(){
		return this.ttl
	}
}

/**
 * @description 根据 TLV Block 创建一个 TTL
 * @param {Block} block
 * @returns {bigint} 
 */
function createTTLByBlock(block){
	var ttl = new TTL()
	try {
		ttl.buildTTLByBlock(block)
		return ttl
	} catch (error) {
		throw error
	}
}

module.exports = {
	TTL: TTL,
	createTTLByBlock: createTTLByBlock
}